package com.ruben.simplescaffold.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.handlers.StrictFill;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.ruben.simplescaffold.pojo.common.BaseEntity;
import com.ruben.simplescaffold.utils.FunctionUtils;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * mybatis-plus配置类
 *
 * @author <achao1441470436@gmail.com>
 * @since 2021/5/20 0020 9:29
 */
@Configuration
public class MybatisPlusConfig {

    /**
     * 分页拦截器
     *
     * @author <achao1441470436@gmail.com>
     * @since 2021/5/20 0020 9:29
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 分页插件
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        // 防止全表更新
        BlockAttackInnerInterceptor blockAttackInnerInterceptor = new BlockAttackInnerInterceptor();
        // 乐观锁
        OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor = new OptimisticLockerInnerInterceptor();
        // 设置请求的页面大于最大页后操作， true调回到首页，false 继续请求  默认false
        paginationInnerInterceptor.setOverflow(false);
        // 限制最大分页请求200条
        paginationInnerInterceptor.setMaxLimit(200L);
        interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor);
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        interceptor.addInnerInterceptor(blockAttackInnerInterceptor);
        return interceptor;
    }

    /**
     * 配置Mybatis-plus自动填充
     *
     * @return com.baomidou.mybatisplus.core.handlers.MetaObjectHandler
     * @author <achao1441470436@gmail.com>
     * @since 2021/7/11 0011 18:31
     */
    @Bean
    public MetaObjectHandler metaObjectHandler() {
        return new MetaObjectHandler() {
            /**
             * 插入元对象字段填充（用于插入时对公共字段的填充）
             *
             * @param metaObject 元对象
             */
            @Override
            public void insertFill(MetaObject metaObject) {
                this.strictInsertFill(findTableInfo(metaObject), metaObject,
                        Arrays.asList(StrictFill.of(FunctionUtils.getAttribute((SFunction<BaseEntity, LocalDateTime>) BaseEntity::getGmtCreate),
                                        LocalDateTime::now, LocalDateTime.class),
                                StrictFill.of(FunctionUtils.getAttribute((SFunction<BaseEntity, LocalDateTime>) BaseEntity::getGmtModified),
                                        LocalDateTime::now, LocalDateTime.class)));
            }

            /**
             * 更新元对象字段填充（用于更新时对公共字段的填充）
             *
             * @param metaObject 元对象
             */
            @Override
            public void updateFill(MetaObject metaObject) {
                this.strictUpdateFill(metaObject,
                        FunctionUtils.getAttribute((SFunction<BaseEntity, LocalDateTime>) BaseEntity::getGmtModified),
                        LocalDateTime::now, LocalDateTime.class);
            }
        };
    }


}
